package com.onvif;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringEscapeUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.onvif.db.entity.CameraEntity;
import com.onvif.db.service.CameraService;

@Component
public class SendOnvifCmd {
	@Autowired
	private RestTemplate restTemplate;
	@Autowired
	CameraService cameraService;
	public String stream(String deviceId,String channelId) {
		// 查询摄像头
		CameraEntity cp = new CameraEntity();
		cp.setDeviceId(deviceId);
		cp.setChannelId(channelId);
		CameraEntity rp = cameraService.findOne(cp);
		if(rp == null) {
			return null;
		}
		//判断是否已获取token
		String token = this.getToken(deviceId, channelId);
		//构造http请求头
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("text/xml;charset=UTF-8");
		headers.setContentType(type);
		HttpEntity<String> formEntity = new HttpEntity<String>(PackageXml.streamUri(rp.getOnvifUsername(),rp.getOnvifPassword(),token), headers);
		//返回结果
		String resultStr = restTemplate.postForObject("http://"+rp.getIp()+":"+rp.getOnvifPort()+"/onvif/device_service", formEntity, String.class);
		//转换返回结果中的特殊字符，返回的结果中会将xml转义，此处需要反转移
		String xmlStr = StringEscapeUtils.unescapeXml(resultStr);
		//JSONObject obj = XML.toJSONObject(tmpStr);
		String reg = "<tt:Uri>(.*?)\\</tt:Uri>";
        Pattern pattern = Pattern.compile(reg);
        // 内容 与 匹配规则 的测试
        Matcher matcher = pattern.matcher(xmlStr);
        if(matcher.find()){
            // 包含前后的两个字符 
            //System.out.println(matcher.group());
            // 不包含前后的两个字符
        	String rtspUrl = matcher.group(1).replace("rtsp://", "rtsp://"+rp.getOnvifUsername()+":"+rp.getOnvifPassword()+"@");
            return rtspUrl;
        }else{
            //System.out.println(" 没有匹配到内容....");
        	return null;
        }
	}
	public Boolean ptz(String deviceId,String channelId,Double leftRight,Double upDown,Double inOut) {
		if(deviceId == null || channelId == null) {
			return false;
		}
		if(leftRight==null) {
			leftRight = 0.0;
		}
		if(upDown==null) {
			upDown = 0.0;
		}
		if(leftRight>1 && leftRight<-1) {
			return false;
		}
		if(upDown>1 && upDown<-1) {
			return false;
		}
		if(inOut>1 && inOut<-1) {
			return false;
		}
		// 查询摄像头
		CameraEntity cp = new CameraEntity();
		cp.setDeviceId(deviceId);
		cp.setChannelId(channelId);
		CameraEntity rp = cameraService.findOne(cp);
		if(rp == null) {
			return false;
		}
		//判断是否已获取token
		String token = this.getToken(deviceId, channelId);
		//构造http请求头
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("text/xml;charset=UTF-8");
		headers.setContentType(type);
		String xml = PackageXml.ptz(rp.getOnvifUsername(),rp.getOnvifPassword(),token,leftRight,upDown,inOut);
		HttpEntity<String> formEntity = new HttpEntity<String>(xml,headers);
		//返回结果
		String resultStr = restTemplate.postForObject("http://"+rp.getIp()+":"+rp.getOnvifPort()+"/onvif/device_service", formEntity, String.class);
		//转换返回结果中的特殊字符，返回的结果中会将xml转义，此处需要反转移
		String xmlStr = StringEscapeUtils.unescapeXml(resultStr);
		//JSONObject obj = XML.toJSONObject(tmpStr);
        return true;
	}
	public String getToken(String deviceId,String channelId) {
		try {
			// 查询摄像头
			CameraEntity cp = new CameraEntity();
			cp.setDeviceId(deviceId);
			cp.setChannelId(channelId);
			CameraEntity rp = cameraService.findOne(cp);
			if(rp == null) {
				return null;
			}
			// 构造http请求头
			HttpHeaders headers = new HttpHeaders();
			MediaType type = MediaType.parseMediaType("text/xml;charset=UTF-8");
			headers.setContentType(type);
			String tokenXml = PackageXml.token(rp.getOnvifUsername(), rp.getOnvifPassword());
			HttpEntity<String> formEntity = new HttpEntity<String>(tokenXml, headers);
			// 返回结果
			String resultStr = restTemplate.postForObject("http://" + rp.getIp() + ":" + rp.getOnvifPort() + "/onvif/device_service", formEntity,String.class);
			// 转换返回结果中的特殊字符，返回的结果中会将xml转义，此处需要反转移
			String xmlStr = StringEscapeUtils.unescapeXml(resultStr);
			SAXReader reader = new SAXReader();
			Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes("UTF-8")));
			Element root = document.getRootElement();
			String token = root.element("Body").element("GetProfilesResponse").elements("Profiles").get(0).attribute("token").getText();
			return token;
		} catch (RestClientException | DocumentException | UnsupportedEncodingException e) {
			return null;
		} 
	}
}
